package com.tcp2.handler;

/**
 * Author: 杨俊辉
 * Time: 2014-09-22 17:35
 * Copyright (C) 2014 Xiamen Yaxon Networks CO.,LTD.
 */

import com.tcp2.msg.rpc.BaseRes;
import com.tcp2.msg.rpc.Dn_9401;
import com.tcp2.msg.rpc.Dn_9402;
import com.tcp2.msg.rpc.SimpleRes;
import com.tcp2.net.PlatformMap;
import com.tcp2.net.SlaveLink;
import com.tcp2.server.ProtoMsg;
import com.tcp2.util.ProtoUtil;
import com.yaxon.vndp.common.util.CodecUtils;
import com.yaxon.vndp.dms.DmsContext;
import com.yaxon.vndp.dms.Message;
import com.yaxon.vndp.dms.MessageHandler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;

import static com.tcp2.server.ProtoConstants.*;

/**
 * 车辆报警信息交互信息处理类
 */
@Service
public class WarnMsgExchangeHandler extends BaseMsgHandler implements MessageHandler {

    protected static Logger logger = LoggerFactory.getLogger(WarnMsgExchangeHandler.class);

    @Autowired
    private PlatformCacheServcie platformCacheServcie;

    @Autowired
    private ScheduledExecutorService gTimer;

    @Override
    public void handle(ProtoMsg msg) {

        logger.info("-> 收到主链路，车辆报警信息交互信息请求，消息id：0x{}，下级平台接入码：{}", CodecUtils.shortToHex((short) msg.msgId), msg.gnssCenterId);

        ByteBuf data = msg.msgData;
        String lpn = ProtoUtil.readOctetString(data, 21);
        byte color = data.readByte();
        int dataType = data.readUnsignedShort(); //数据类型
        int dataLen = data.readInt();//后续数据长度
        if (dataLen != data.readableBytes()) {
            logger.warn("(UP_EXG_MSG):数据长度不一致");
            return;
        }
        switch (dataType) {
            case UP_WARN_MSG_URGE_TODO_ACK:
                //doUpWarnMsgUrgeTodoAck(lpn, color, data, dataType);
                break;
            case UP_WARN_MSG_ADPT_INFO:
                //doUpWarnMsgAdptInfo(lpn, color, data, dataType);
                break;
            case UP_WARN_MSG_ADPT_TODO_INFO:
                doUpWarnMsgAdptTodoInfo(lpn, color, data, dataType);
                break;
            default:
                throw new RuntimeException("未知子业务类型：dataType=" + CodecUtils.shortToHex((short) dataType));
        }
    }

    /**
     * RPC消息处理器
     */
    @Override
    public void onReceive(DmsContext ctx, Message req) {
        if (req instanceof Dn_9401) {//报警督办请求  DOWN_WARN_MSG_URGE_TODO_REQ
            //doDownWarnMsgUrgeTodoReq(ctx, (Dn_9401) req);
        }else if (req instanceof Dn_9402) {//报警预警 DOWN_WARN_MSG_INFORM_TIPS
            doDownWarnMsgInformTips(ctx, (Dn_9402) req);
        } else {
            throw new RuntimeException("未知的请求消息类型: " + req.getClass().getName());
        }
    }



    private void doUpWarnMsgAdptTodoInfo(String lpn, byte color, ByteBuf data, int dataType) {
        logger.info("-> 收到主链路，上报车辆{}颜色{}警报处理结果，子业务类型：0x{}",lpn,color, CodecUtils.shortToHex((short) dataType));
        logger.info("字节数{}，16进制:{}", data.readableBytes(), ByteBufUtil.hexDump(data).replaceAll("\\w{2}(?!$)", "$0 ").toUpperCase());

        SimpleRes r = new SimpleRes();
        try {
            int info_id = data.readInt();//信息id
            byte handle_result = data.readByte(); //处理结果



        } catch (Exception e) {
            r.setRc(BaseRes.RC_FAIL);
            logger.warn("上报警报处理结果失败", e);
        }
    }




    private void doDownWarnMsgInformTips(final DmsContext ctx, Dn_9402 req) {
        logger.info("<- 发送从链路，发送报警预警，车牌号 ：{}，颜色：{}", req.getLpn(), req.getCol());
        //上级平台可根据车辆定位数据分析产生报警预警信息，或者将跨域车辆的报警信息，即
        //可下发到相关下级平台，下级平台不必处理报警预警信息和转发跨域车辆报警信息
        SimpleRes res = new SimpleRes();
        try {
            Validate.notNull(req.getLpn(), "对象类型不能为空");
            Validate.notNull(req.getCol(), "对象id不能为空");
            Validate.notNull(req.getWarnSrc(), "报警来源不能为空");
            Validate.notNull(req.getWarnType(), "报警类型不能为空");
            Validate.notNull(req.getWarnTime(), "报警时间不能为空");
            Validate.notNull(req.getWarnContent(), "报警内容不能为空");
        } catch (Exception e) {
            res.setRc(BaseRes.RC_FAIL);
            res.setErrMsg("请求参数不合法");
            ctx.reply(res);
            return;
        }

        try {
            ProtoMsg out = new ProtoMsg();
            out.msgId = DOWN_WARN_MSG;
            ByteBuf data = Unpooled.buffer(0);
            out.msgData = data;

            ProtoUtil.writeOctetString(data, req.getLpn(), 21);
            data.writeByte(req.getCol());
            data.writeShort(DOWN_WARN_MSG_INFORM_TIPS);
            int startIndex = data.writerIndex();
            data.writeInt(0);//数据长度
            data.writeByte(req.getWarnSrc());
            data.writeShort(req.getWarnType());
            ProtoUtil.writeTime(data, req.getWarnTime());
            ProtoUtil.writeU32String(data, req.getWarnContent());
            int dataLen = data.writerIndex() - startIndex - 4;
            data.setInt(startIndex, dataLen); //写入实际的数据长度




            res.setRc(BaseRes.RC_OK);
            ctx.reply(res);
        } catch (Exception e) {
            logger.warn("发送报警预警失败", e);
            res.setRc(BaseRes.RC_FAIL);
            ctx.reply(res);
        }
    }


}